﻿using System.Text.RegularExpressions;

namespace 计算基础指标公式
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var targets = new List<Target>()
            {
                new  Target{Id="A1",Method = Method.Auto,  Formula = ""},
                new  Target{Id="A2",Method = Method.Auto,  Formula = ""},
                new  Target{Id="A3",Method = Method.Calc,  Formula = "|A1|+|A2|"},
                new  Target{Id="A4",Method = Method.Calc,  Formula = "|A1|+|A2|+|A3|"},
                new  Target{Id="A5",Method = Method.Calc,  Formula = "(|A4|)*2"},
                new  Target{Id="A6",Method = Method.Calc,  Formula = "(|A5|)*2"},
                new  Target{Id="A7",Method = Method.Calc,  Formula = "(|A1|)*2"},
            };
            //获取基础指标
            //var formula = targets[4].Formula;
            //var baseFormula = GetBaseFormula(formula, targets);
            //Console.WriteLine($"基础指标公式: {baseFormula}");

            var result = new List<Target>();
             GetTargets("A2", targets,ref result);
            foreach (var item in result)
            {
                Console.WriteLine(item.Id);
            }

            Console.ReadKey();
        }

        public static List<Target> GetTargets(string id, List<Target> targets,ref List<Target> result)
        {
            var target = targets.FirstOrDefault(c=>c.Id==id);
            if (target!=null)
            {
                var fo = "|"+target.Id+"|";
                var tars = targets.Where(c => c.Formula.Contains(fo)).ToList();
                foreach (var tar in tars)
                {
                    if (!result.Contains(tar))
                    {
                        result.Add(tar);
                    }
                    GetTargets(tar.Id, targets, ref result);
                }
            }
            return result;
        }


        public static string GetBaseFormula(string formula, List<Target> targets)
        {
            var subFormulasTargets = new List<string>();
            Regex p = new Regex(@"(\|(.*?)\|)");
            foreach (Match mch in p.Matches(formula))
            {
                string indiCode = mch.Value.Trim();
                indiCode = indiCode.Substring(1, indiCode.Length - 2);  //去掉首尾的中括号
                subFormulasTargets.Add(indiCode);
            }

            //遍历解析的指标Id，判断是不是计算指标
            foreach (var item in subFormulasTargets)
            {
                var itemTarget = targets.FirstOrDefault(t => t.Id == item);
                if (itemTarget!=null)
                {
                    //当前指标是计算指标，则替换当前部分继续递归
                   if (itemTarget.Method==Method.Calc)
                   {
                        var itemFormula = itemTarget.Formula;
                        formula = formula.Replace("|"+item+"|", "("+itemFormula+")");
                        formula = GetBaseFormula(formula, targets);
                   }
                }
            }
            return formula;
        }
    }
    class Target
    {
        /// <summary>
        /// 指标Id
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// 指标采集方式
        /// </summary>
        public Method Method { get; set; }
        /// <summary>
        /// 指标公示
        /// </summary>
        public string Formula { get; set; }
    }
    enum Method 
    { 
        /// <summary>
        /// 公式计算
        /// </summary>
        Calc =1,
        /// <summary>
        /// 手工填报
        /// </summary>
        Auto =2,
    }
}
